
package com.hlkj.pay.app.merchant.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.LocalContext;
import com.hlkj.framework.common.provider.Aes256EncryptionProvider;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.common.IAuthCodeService;
import com.hlkj.pay.app.common.ICommonAppService;
import com.hlkj.pay.app.merchant.IMerchantInfoAppService;
import com.hlkj.pay.app.transfer.MerchantTransfer;
import com.hlkj.pay.app.transfer.PayWayDoToResp;
import com.hlkj.pay.common.AdminUserResultCode;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.config.SmsTemplateProperties;
import com.hlkj.pay.dto.LocalAdminUserRequest;
import com.hlkj.pay.dto.admin.AdminUserDto;
import com.hlkj.pay.dto.common.DefaultConfig;
import com.hlkj.pay.dto.merchant.MerchantInfoRegisterDto;
import com.hlkj.pay.dto.merchant.ProviderChannelFeeConfigList;
import com.hlkj.pay.dto.pay.PayWayQueryDto;
import com.hlkj.pay.enums.AdminUserEnum;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.common.PlatFormConfigDO;
import com.hlkj.pay.infrastructure.model.merchant.DefaultFeeConfigDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantConfigDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantInfoDO;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelFeeConfigDO;
import com.hlkj.pay.infrastructure.model.token.TokenSecretDO;
import com.hlkj.pay.service.admin.IAdminUserService;
import com.hlkj.pay.service.common.IBusinessLogService;
import com.hlkj.pay.service.common.IOperatedLogService;
import com.hlkj.pay.service.common.IPlatFormConfigService;
import com.hlkj.pay.service.merchant.IMerchantApplicationService;
import com.hlkj.pay.service.merchant.IMerchantConfigService;
import com.hlkj.pay.service.merchant.IMerchantDefaultConfigService;
import com.hlkj.pay.service.merchant.IMerchantService;
import com.hlkj.pay.service.merchant.impl.MerchantHandler;
import com.hlkj.pay.service.pay.IPayWayService;
import com.hlkj.pay.service.pay.IProviderService;
import com.hlkj.pay.service.token.ITokenService;
import com.hlkj.pay.vo.admin.req.user.AdminUserCallTranPwdReq;
import com.hlkj.pay.vo.admin.req.user.AdminUserUpdateTranPwdReq;
import com.hlkj.pay.vo.common.req.SmsSendReq;
import com.hlkj.pay.vo.merchant.req.MerchantConfigReq;
import com.hlkj.pay.vo.merchant.req.info.MerchantFeeConfigReq;
import com.hlkj.pay.vo.merchant.req.info.MerchantInfoUpdateReq;
import com.hlkj.pay.vo.merchant.req.info.MerchantRegisterReq;
import com.hlkj.pay.vo.merchant.req.info.UpdateMerchantStatusReq;
import com.hlkj.pay.vo.merchant.resp.info.MerchantFeeConfigResp;
import com.hlkj.pay.vo.pay.resp.PayWayResp;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/09/12 11:40
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Validated
public class MerchantInfoAppServiceImpl implements IMerchantInfoAppService {

    private final IMerchantService merchantService;
    private final IMerchantConfigService merchantConfigService;

    private final IAuthCodeService authCodeService;

    private final IAdminUserService userService;

    private final ITokenService tokenService;

    private final IBusinessLogService businessLogService;

    private final IProviderService providerService;

    private final MerchantFeeParamsCheck merchantFeeParamsCheck;

    private final IPayWayService payWayService;

    private final IPlatFormConfigService platFormConfigService;

    private final IMerchantDefaultConfigService merchantDefaultConfigService;

    private final MerchantHandler merchantHandler;

    private final IMerchantApplicationService merchantApplicationService;

    private final Aes256EncryptionProvider aes256EncryptionProvider;

    private final SmsTemplateProperties smsTemplateProperties;

    private final ICommonAppService commonAppService;

    private final IOperatedLogService merchantLogService;

    @Override
    public CommonResult<String> register(MerchantRegisterReq merchantRegisterReq) {
        if (!merchantRegisterReq.getPwd().equals(merchantRegisterReq.getPwdConfirm())) {
            return CommonResult.error(AdminUserResultCode.SECOND_PASSWORD_IS_INCONSISTENT);
        }

        // 用户名校验
        String account = merchantRegisterReq.getAccount();
        // 总长度6位
        if(account.length() < 6){
            return CommonResult.error(AdminUserResultCode.USERNAME_LENGTH_ERROR);
        }
        // 首字符必须英文
        if(!ReUtil.isMatch("^[A-Za-z].*$",account)){
            return CommonResult.error(AdminUserResultCode.USERNAME_FIRST_MUST_BE_ENGLISH);
        }
        // 不能含有敏感字admin
        if(StrUtil.containsAnyIgnoreCase(account,"admin")){
            return CommonResult.error(AdminUserResultCode.USERNAME_HAS_SENSITIVE);
        }

        // 1 参数校验
        CommonResult<Void> voidCommonResult = authCodeService.checkAuthCode(merchantRegisterReq.getPhone(), AdminUserEnum.AdminAuthCodeEnum.ADMIN_AUTH_CODE_REGISTER,
                merchantRegisterReq.getSmsCode());
        if (!voidCommonResult.isSuccess()) {
            return CommonResult.error(voidCommonResult.getCode(),voidCommonResult.getMsg());
        }
        try {
            AdminUserDto adminUserDto = userService.queryUserByPhone(merchantRegisterReq.getPhone(),null);
            if (adminUserDto != null) {
                return CommonResult.error(AdminUserResultCode.USER_DOES_EXIST);
            }
        }
        catch (Exception e) {
            return CommonResult.error(CommonResultCode.DATA_ENCRYPT_ERROR);
        }

        // 2 商户信息生成（包含应用id）
        MerchantInfoRegisterDto merchantInfoRegisterDto = MerchantTransfer.INSTANCE.merchantInfoDto(merchantRegisterReq);
        TokenSecretDO tokenSecretDO = tokenService.queryTenantInfoByDomain();
        if (tokenSecretDO == null) {
            return CommonResult.error(CommonResultCode.APP_NOT_EXIST);
        }
        CommonEnum.SYS_TYPE sysType = CommonEnum.SYS_TYPE.MERCHANT;
        merchantInfoRegisterDto.setSysType(sysType);
        merchantInfoRegisterDto.setRegisterChannel(2);
        merchantInfoRegisterDto.setSnType(MerchantEnum.MERCHANT_SN_TYPE.MERCHANT.getCode());
        return merchantHandler.register(merchantInfoRegisterDto, null, null);
    }

    @Override
    public CommonResult<Void> updateMerchantInfo(MerchantInfoUpdateReq merchantInfoUpdateReq) {
        log.info("updateMerchantInfo merchantInfoUpdateReq:{}", JsonUtils.toJsonString(merchantInfoUpdateReq));
        try {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(merchantInfoUpdateReq.getSn());
            if (merchantInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantInfoDO updateMerchantInfoDO = BeanUtil.copyProperties(merchantInfoUpdateReq, MerchantInfoDO.class, "scene");
            if (merchantInfoUpdateReq.getScene() != null) {
                updateMerchantInfoDO.setScene(JsonUtils.toJsonString(merchantInfoUpdateReq.getScene()));
            }
            if (updateMerchantInfoDO.getOperateId() == null)
                updateMerchantInfoDO.setOperateId(0);
            // 代理商信息
            MerchantInfoDO agentInfoDO = merchantService.queryMerchantNoCache(merchantInfoDO.getSuperAgent());
            // 外扣底价判断
            if(merchantInfoUpdateReq.getCommRateBase() != null){
                if(agentInfoDO != null && agentInfoDO.getCommRateBase() != null){
                    if(merchantInfoUpdateReq.getCommRateBase().compareTo(agentInfoDO.getCommRateBase()) < 0){
                        return CommonResult.error(MerchantResultCode.MERCHANT_COMM_RATE_ERROR);
                    }
                }
            }

            // 商户余额拦截
            Integer merblockBal = merchantInfoUpdateReq.getBlockBal() == null?0:merchantInfoUpdateReq.getBlockBal();
            if(agentInfoDO != null && agentInfoDO.getBlockBal() != null){
                // 代理商拦截
                if(agentInfoDO.getBlockBal() == 1 && merblockBal != 1 ){
                    return CommonResult.error(MerchantResultCode.MERCHANT_COMM_BLOCKBAL_ERROR);
                }
            }

            merchantService.updateMerchantBySn(updateMerchantInfoDO);
            // 修改配置
            if (!CollectionUtils.isEmpty(merchantInfoUpdateReq.getChannelCodeList()) && !CollectionUtils.isEmpty(merchantInfoUpdateReq.getProviderCodeList())) {
                MerchantConfigReq merchantConfigReq = new MerchantConfigReq();
                merchantConfigReq.setSn(merchantInfoUpdateReq.getSn());
                merchantConfigReq.setProviderCodeList(merchantInfoUpdateReq.getProviderCodeList());
                merchantConfigReq.setChannelCodeList(merchantInfoUpdateReq.getChannelCodeList());
                saveConfig(merchantConfigReq);
            }
            merchantLogService.save(merchantInfoDO.getId(), MerchantEnum.MERCHANT_LOG_TYPE.MERCHANT, "商户信息修改", "商户基本信息修改");
            businessChangeLog(merchantInfoDO, updateMerchantInfoDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updateStatus(UpdateMerchantStatusReq updateStatusReq) {
        log.info("updateStatus updateStatusReq:{}", JsonUtils.toJsonString(updateStatusReq));
        try {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(updateStatusReq.getSn());
            if (merchantInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantInfoDO updateMerchantInfoDO = new MerchantInfoDO();
            updateMerchantInfoDO.setStatus(updateStatusReq.getStatus());
            updateMerchantInfoDO.setSn(updateStatusReq.getSn());
            merchantService.updateMerchantBySn(updateMerchantInfoDO);
            String remark = "启用商户";
            if (updateStatusReq.getStatus() == CommonEnum.YES_NO_TYPE.NO.getCode()) remark = "关闭商户";
            merchantLogService.save(merchantInfoDO.getId(), MerchantEnum.MERCHANT_LOG_TYPE.MERCHANT, "修改状态", remark);
            businessChangeLog(merchantInfoDO, updateMerchantInfoDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updateTranStatus(UpdateMerchantStatusReq updateStatusReq) {
        log.info("updateTranStatus updateStatusReq:{}", JsonUtils.toJsonString(updateStatusReq));
        try {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(updateStatusReq.getSn());
            if (merchantInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantInfoDO updateMerchantInfoDO = new MerchantInfoDO();
            updateMerchantInfoDO.setApiStatus(updateStatusReq.getStatus());
            updateMerchantInfoDO.setSn(updateStatusReq.getSn());
            merchantService.updateMerchantBySn(updateMerchantInfoDO);
            String remark = "商户开启交易状态";
            if (updateStatusReq.getStatus() == CommonEnum.YES_NO_TYPE.NO.getCode()) remark = "商户关闭交易状态";
            merchantLogService.save(merchantInfoDO.getId(), MerchantEnum.MERCHANT_LOG_TYPE.MERCHANT, "修改交易状态", remark);
            businessChangeLog(merchantInfoDO, updateMerchantInfoDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> delMerchant(String sn) {
        log.info("delMerchant sn:{}", sn);
        try {
            if (!StringUtils.hasText(sn)) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(sn);
            if (merchantInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            merchantService.delMerchant(merchantInfoDO.getSn());
            merchantConfigService.delConfig(merchantInfoDO.getSn());
            merchantApplicationService.delMerchantAppBySn(sn);
            MerchantInfoDO updateMerchantInfoDO = BeanUtil.copyProperties(merchantInfoDO, MerchantInfoDO.class);
            merchantInfoDO.setDeleteFlag(Boolean.TRUE);
            businessChangeLog(merchantInfoDO, updateMerchantInfoDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateMerchantInfo error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> saveConfig(MerchantConfigReq merchantConfigReq) {
        log.info("saveConfig merchantConfigReq:{}", JsonUtils.toJsonString(merchantConfigReq));
        try {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(merchantConfigReq.getSn());
            if (merchantInfoDO == null) {
                // 需要获取系统默认配置
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantConfigDO merchantConfigDb = merchantConfigService.queryConfig(merchantConfigReq.getSn());
            if (merchantConfigDb == null) {
                merchantConfigDb = new MerchantConfigDO();
                merchantConfigDb.setSn(merchantConfigReq.getSn());
                merchantConfigDb.setChannelCode(JsonUtils.toJsonString(merchantConfigReq.getChannelCodeList()));
                merchantConfigDb.setProviderCode(JsonUtils.toJsonString(merchantConfigReq.getProviderCodeList()));
                merchantConfigService.saveConfig(merchantConfigDb);
                merchantLogService.save(merchantInfoDO.getId(), MerchantEnum.MERCHANT_LOG_TYPE.MERCHANT, "添加商户配置", "新增配置");
            }
            else {
                merchantConfigDb.setChannelCode(JsonUtils.toJsonString(merchantConfigReq.getChannelCodeList()));
                merchantConfigDb.setProviderCode(JsonUtils.toJsonString(merchantConfigReq.getProviderCodeList()));
                merchantConfigService.updateConfig(merchantConfigDb);
                merchantLogService.save(merchantInfoDO.getId(), MerchantEnum.MERCHANT_LOG_TYPE.MERCHANT, "修改商户配置", "修改配置");

                MerchantConfigDO afterPayMerchantInfo = BeanUtil.copyProperties(merchantConfigDb, MerchantConfigDO.class);
                afterPayMerchantInfo.setChannelCode(JsonUtils.toJsonString(merchantConfigReq.getChannelCodeList()));
                afterPayMerchantInfo.setProviderCode(JsonUtils.toJsonString(merchantConfigReq.getProviderCodeList()));
                // businessChangeLog(merchantConfigDb, afterPayMerchantInfo);
            }
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("saveConfig error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> saveFeeConfig(@Valid MerchantFeeConfigReq merchantFeeConfigReq) {
        log.info("saveFeeConfig merchantFeeConfigReq:{}", JsonUtils.toJsonString(merchantFeeConfigReq));
        try {
            List<ProviderChannelFeeConfigList> providerChannelFeeConfigListReq = merchantFeeConfigReq.getProviderChannelFeeConfigList();
            providerChannelFeeConfigListReq = providerChannelFeeConfigListReq.stream()
                    .filter(providerChannelFeeConfigReq -> CommonEnum.YES_NO_TYPE.YES.getCode().equals(providerChannelFeeConfigReq.getStatus())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(providerChannelFeeConfigListReq)) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest) LocalContext.get();
            if (providerChannelFeeConfigListReq.size() > 5) {
                localAdminUserRequest.setParams(null);
            }
            else {
                localAdminUserRequest.setParams(JsonUtils.toJsonString(merchantFeeConfigReq));
            }
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(merchantFeeConfigReq.getSn());
            if (merchantInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantConfigDO merchantConfigDb = merchantConfigService.queryConfig(merchantFeeConfigReq.getSn());
            if (merchantConfigDb == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_CONFIG_NOT_EXIST);
            }
            // 获取服务商的配置
            List<String> providerCodeList = merchantConfigDb.getProviderCodeList();
            if (CollectionUtils.isEmpty(providerCodeList)) {
                return CommonResult.error(MerchantResultCode.MERCHANT_CONFIG_PROVIDER_NOT_EXIST);
            }
            // 获取服务商的支付通道
            List<String> channelCodeList = merchantConfigDb.getChannelCodeList();
            if (CollectionUtils.isEmpty(channelCodeList)) {
                return CommonResult.error(MerchantResultCode.MERCHANT_CONFIG_CHANNEL_NOT_EXIST);
            }

            List<ProviderChannelFeeConfigDO> providerChannelFeeConfigList = providerService.queryEffectFeeConfig(providerCodeList, channelCodeList);
            // 配置参数校验
            CommonResult<Void> checkParams = merchantFeeParamsCheck.submitCheckParams(providerChannelFeeConfigList, providerChannelFeeConfigListReq);
            if (!checkParams.isSuccess()) {
                return CommonResult.error(checkParams.getCode(), checkParams.getMsg());
            }
            JSONConfig jsonConfig = new JSONConfig();
            jsonConfig.setIgnoreNullValue(true);
            boolean isAdd = false;
            if (!StringUtils.hasText(merchantConfigDb.getFeeConfig()))
                isAdd = true;
            merchantConfigDb.setFeeConfig(JsonUtils.toJsonStr(providerChannelFeeConfigListReq, jsonConfig));
            merchantConfigService.updateConfig(merchantConfigDb);
            if (isAdd) {
                merchantLogService.save(merchantInfoDO.getId(), MerchantEnum.MERCHANT_LOG_TYPE.MERCHANT, "添加商户费率", "新增商户费率");
            } else
                merchantLogService.save(merchantInfoDO.getId(), MerchantEnum.MERCHANT_LOG_TYPE.MERCHANT, "修改商户费率", "修改商户费率");
            // MerchantConfigDO afterPayMerchantInfo =
            // BeanUtil.copyProperties(merchantConfigDb, MerchantConfigDO.class);
            // afterPayMerchantInfo.setFeeConfig(JsonUtils.toJsonString(providerChannelFeeConfigListReq));
            // businessChangeLog(merchantConfigDb, afterPayMerchantInfo);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("saveConfig error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<List<MerchantFeeConfigResp>> queryFeeConfig(String sn) {
        MerchantConfigDO merchantConfigDO = queryConfig(sn);
        if (merchantConfigDO == null) {
            return CommonResult.success(null);
        }
        List<PayWayDO> payWayList = payWayService.queryList(new PayWayQueryDto());
        Map<String, MerchantFeeConfigResp> merchantFeeConfigRespMap = new HashMap<>();
        if (StringUtils.hasText(merchantConfigDO.getFeeConfig())) {
            List<MerchantFeeConfigResp> providerChannelFeeConfigList = JsonUtils.parseArray(merchantConfigDO.getFeeConfig(), MerchantFeeConfigResp.class);
            merchantFeeConfigRespMap = providerChannelFeeConfigList.stream()
                    .collect(Collectors.toMap(providerChannel -> providerChannel.getPayWayCode(), Function.identity(), (t1, t2) -> t1));
        }
        List<MerchantFeeConfigResp> merchantFeeConfigResps = new ArrayList<>();
        Map<String, MerchantFeeConfigResp> finalMerchantFeeConfigRespMap = merchantFeeConfigRespMap;
        List<PayWayResp> payWayResps = PayWayDoToResp.INSTANCE.payWayRespList(payWayList);
        Map<String, PayWayResp> payMap = payWayResps.stream().collect(Collectors.toMap(payWayResp -> payWayResp.getCode(), Function.identity(), (t1, t2) -> t1));
        payMap.forEach((key, value) -> {
            PayWayResp payWayResp = payMap.get(key);
            MerchantFeeConfigResp merchantFeeConfigResp = finalMerchantFeeConfigRespMap.get(key);
            if (merchantFeeConfigResp == null) {
                merchantFeeConfigResp = new MerchantFeeConfigResp();
                merchantFeeConfigResp.setPayWayCode(key);
                merchantFeeConfigResp.setSeniorFeeType(payWayResp.getSeniorFeeType());
                merchantFeeConfigResp.setApplyType(payWayResp.getApplyType());
                merchantFeeConfigResp.setStepFeeType(payWayResp.getStepFeeType());
                merchantFeeConfigResp.setStatus(CommonEnum.YES_NO_TYPE.NO.getCode());
            }
            merchantFeeConfigResp.setPayWay(payWayResp);
            merchantFeeConfigResps.add(merchantFeeConfigResp);
        });
        return CommonResult.success(merchantFeeConfigResps);
    }

    @Override
    public MerchantConfigDO queryConfig(String sn) {
        MerchantConfigDO merchantConfigDO = merchantConfigService.queryConfig(sn);
        // 商户配置不存在 从默认配置中读取
        if (merchantConfigDO == null) {
            List<PlatFormConfigDO> platFormConfigList = platFormConfigService.platFormConfigList(CommonEnum.CONFIG_TYPE.DEFAULT.getType());
            if (CollectionUtils.isEmpty(platFormConfigList)) {
                return null;
            }
            PlatFormConfigDO platFormConfigDO = platFormConfigList.get(0);
            DefaultConfig defaultConfig = JsonUtils.parseObject(platFormConfigDO.getConfigValue(), DefaultConfig.class);
            if (defaultConfig.getOtherConfig() == null) {
                return null;
            }
            merchantConfigDO = new MerchantConfigDO();
            merchantConfigDO.setProviderCodeList(defaultConfig.getOtherConfig().getProviderCodeList());
            merchantConfigDO.setChannelCodeList(defaultConfig.getOtherConfig().getChannelCodeList());
            merchantConfigDO.setSn(sn);
        }
        if (StringUtils.isEmpty(merchantConfigDO.getFeeConfig())) {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(sn);
            DefaultFeeConfigDO defaultFeeConfigDO;
            if (StringUtils.hasText(merchantInfoDO.getSuperAgent())) {
                defaultFeeConfigDO = merchantDefaultConfigService.queryDetail(CommonEnum.SYS_TYPE.BUSINESS.getCode(), null);
            }
            else {
                defaultFeeConfigDO = merchantDefaultConfigService.queryDetail(CommonEnum.SYS_TYPE.AGENT.getCode(), merchantInfoDO.getSuperAgent());
            }
            if (defaultFeeConfigDO != null) {
                merchantConfigDO.setFeeConfig(defaultFeeConfigDO.getFeeConfig());
            }
        }
        return merchantConfigDO;
    }

    @Override
    public CommonResult<Void> updateTranPwd(AdminUserUpdateTranPwdReq adminUserUpdateTranPwdReq) {
        log.info("updateTranPwd adminUserUpdateTranPwdReq:{}", JsonUtils.toJsonString(adminUserUpdateTranPwdReq));
        try {
            LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest) LocalContext.get();
            AdminUserDto beforeRole = userService.queryUserDto(localAdminUserRequest.getUserId());
            if (beforeRole == null) {
                return CommonResult.error(AdminUserResultCode.USER_DOES_NOT_EXIST);
            }
            if (!adminUserUpdateTranPwdReq.getPwd().equals(adminUserUpdateTranPwdReq.getPwdConfirm())) {
                return CommonResult.error(AdminUserResultCode.SECOND_PASSWORD_IS_INCONSISTENT);
            }
            String passwordEncrypt = aes256EncryptionProvider.encryptString(adminUserUpdateTranPwdReq.getPwd());
            if(!StringUtils.hasText(localAdminUserRequest.getSn())){
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            MerchantInfoDO merchantInfoDO=new MerchantInfoDO();
            merchantInfoDO.setSn(localAdminUserRequest.getSn());
            merchantInfoDO.setTranPwdEncrypt(passwordEncrypt);
            // updatePwd
            merchantService.updateMerchantBySn(merchantInfoDO);
            return CommonResult.success(null);
        }
        catch (Exception e) {
            log.error("updatePwd error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> callTranPwd(AdminUserCallTranPwdReq adminUserCallTranPwdReq) {
        log.info("updateTranPwd adminUserUpdatePwdReq:{}", JsonUtils.toJsonString(adminUserCallTranPwdReq));
        try {
            LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest) LocalContext.get();
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(localAdminUserRequest.getSn());

            AdminUserDto adminUserDto = userService.queryUserDto(localAdminUserRequest.getUserId());
            if (adminUserDto == null) {
                return CommonResult.error(AdminUserResultCode.USER_DOES_NOT_EXIST);
            }
            String oldPhone = aes256EncryptionProvider.decryptString(adminUserDto.getPhoneEncrypt());
            CommonResult<Void> voidCommonResult = authCodeService.checkAuthCode(oldPhone, AdminUserEnum.AdminAuthCodeEnum.ADMIN_AUTH_CODE_CALL_TRAN_PWD,
                    adminUserCallTranPwdReq.getSmsCode());
            if (!voidCommonResult.isSuccess()) {
                return CommonResult.error(CommonResultCode.AUTH_CODE_ERROR);
            }
            String tranPwd = aes256EncryptionProvider.decryptString(merchantInfoDO.getTranPwdEncrypt());
            String phone = aes256EncryptionProvider.decryptString(adminUserDto.getPhoneEncrypt());
            String templateCode = smsTemplateProperties.getCallTranPwdNotify();
            try {
                SmsSendReq smsSendReq = new SmsSendReq();
                smsSendReq.setPassWord(tranPwd);
                smsSendReq.setPhone(phone);
                smsSendReq.setTemplateCode(templateCode);
                commonAppService.sendSms(smsSendReq);
            }
            catch (Exception e) {

            }
            return CommonResult.success(null);
        }
        catch (Exception e) {
            log.error("updatePwd error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    /**
     * log object
     *
     * @param beforeMerchantInfo
     * @param afterPayMerchantInfo
     * @return
     */
    void businessChangeLog(MerchantInfoDO beforeMerchantInfo, MerchantInfoDO afterPayMerchantInfo) {
        businessLogService.addBusinessChangeLog(beforeMerchantInfo.getSn(), MerchantEnum.CHANGE_LOG_TYPE.MERCHANT_INFO.getCode(), CommonEnum.CHANGE_LOG_MODEL_TYPE.MERCHANT,
                beforeMerchantInfo, afterPayMerchantInfo);
    }

    /**
     * log object
     *
     * @param beforeMerchantInfo
     * @param afterPayMerchantInfo
     * @return
     */
    void businessChangeLog(MerchantConfigDO beforeMerchantInfo, MerchantConfigDO afterPayMerchantInfo) {
        businessLogService.addBusinessChangeLog(beforeMerchantInfo.getSn(), MerchantEnum.CHANGE_LOG_TYPE.MERCHANT_CONFIG.getCode(), CommonEnum.CHANGE_LOG_MODEL_TYPE.MERCHANT,
                beforeMerchantInfo, afterPayMerchantInfo);
    }

}
